package service

import (
	"context"
	"go-mall/dao"
	"go-mall/model"
	"go-mall/pkg/e"
	"go-mall/pkg/util"
	"go-mall/serializer"
	"strconv"
	"strings"
)

type OrderService struct {
	ProductId uint    `json:"product_id" form:"product_id"`
	Num       int     `json:"num" form:"num"`
	AddressId uint    `json:"address_id" form:"address_id"`
	Money     float64 `json:"money" form:"money"`
	BossId    uint    `json:"boss_id" form:"boss_id"`
	UserId    uint    `json:"user_id" form:"user_id"`
	OrderNum  int     `json:"order_num" form:"order_num"`
	Type      int     `json:"type" form:"type"` //0全部,1待付款,2待收货,3待评价,4售后

	model.BasePage
}

func (service *OrderService) Create(ctx context.Context, requestBody *model.RequestBody, uId uint) serializer.Response {
	orderDao := dao.NewOrderDao(ctx)
	code := e.Success

	// 开启事务

	tx := orderDao.Begin()
	//没有用户地址
	if requestBody.List[0].AddressId == 0 {

		code = e.ErrorAddressNot
		return serializer.Response{
			Status: code,
			Msg:    e.GetMsg(code),
		}
	}

	//地址是否存在
	addressDao := dao.NewAddressDao(ctx)
	address, err := addressDao.GetAddressByAid(strconv.Itoa(int(requestBody.List[0].AddressId)))
	if err != nil {
		code = e.ErrorAddressNot
		return serializer.Response{
			Status: code,
			Msg:    e.GetMsg(code),
		}
	}

	//订单uuid
	uuid := util.NewUuid()

	var orderPrice float64 //总价格
	var orderNum int       //总数量
	var orderItems []model.OrderItem
	productDao := dao.NewProductDao(ctx)
	for _, item := range requestBody.List {
		product, err := productDao.GetProductById(item.ProductId)
		if err != nil {
			continue
		}

		//数量是否足够
		if item.Num > product.Num {
			code = e.ErrorOrderNum
			return serializer.Response{
				Status: code,
				Msg:    product.Name + "商品商量不足,目前还剩下" + string(rune(product.Num)),
			}
		}

		//减去商品数量
		productNum := product.Num - item.Num
		err = productDao.UpdateProductNum(product.ID, productNum)
		if err != nil {
			tx.Rollback()
			code = e.Error
			return serializer.Response{
				Status: code,
				Msg:    e.GetMsg(code),
			}
		}
		//计算价格 数量
		price, _ := strconv.Atoi(product.DiscountPrice)
		money := price * item.Num
		orderNum += item.Num
		orderPrice += float64(money)

		//订单item
		orderItem := model.OrderItem{
			OrderId:   uuid,
			ProductId: product.ID,
			AddressId: address.ID,
			BossId:    product.BossId,
			Num:       item.Num,
			Money:     float64(money),
			Type:      1,
		}
		orderItems = append(orderItems, orderItem)
	}

	//创建item
	err = orderDao.CreateOrderItem(&orderItems)
	if err != nil {
		tx.Rollback()
		code = e.ErrorOrder
		return serializer.Response{
			Status: code,
			Msg:    e.GetMsg(code),
		}
	}

	//删除购物车
	result := strings.Split(requestBody.CartIds, ",")
	var carts []model.Cart
	for _, item := range result {
		var cart model.Cart
		cart.ID = util.StrToUint(item)
		carts = append(carts, cart)
	}
	cartDao := dao.NewCartDao(ctx)
	err = cartDao.DeleteCartListByCartId(carts, uId)
	if err != nil {
		tx.Rollback()
		code = e.ErrorCartDelete
		return serializer.Response{
			Status: code,
			Msg:    e.GetMsg(code),
		}
	}

	//创建订单
	order := &model.Order{
		Num:     orderNum,
		OrderId: uuid,
		UserId:  uId,
		Type:    1,
		Money:   orderPrice,
	}
	err = orderDao.CreateOrder(order)
	if err != nil {
		tx.Rollback()
		code = e.ErrorOrder
		return serializer.Response{
			Status: code,
			Msg:    e.GetMsg(code),
		}
	}
	return serializer.Response{
		Status: code,
		Msg:    e.GetMsg(code),
		Data:   serializer.BuildOrder(order),
	}

}
func (service *OrderService) List(ctx context.Context, uId uint) serializer.Response {
	code := e.Success
	if service.PageSize == 0 {
		service.PageSize = 15
	}
	orderDao := dao.NewOrderDao(ctx)

	var orderList []*model.Order
	var total int64

	//查询全部
	if service.Type == 0 {
		orderList, total, err := orderDao.ListOrder(uId, service.BasePage)
		if err != nil {
			code = e.Error
			return serializer.Response{
				Status: code,
				Msg:    e.GetMsg(code),
			}
		}
		return serializer.BuildListResponse(serializer.BuildOrders(ctx, orderList), uint(total))
	}
	//分类查询
	orderList, total, err := orderDao.ListOrderByUserIdAndType(uId, service.Type, service.BasePage)
	if err != nil {
		code = e.Error
		return serializer.Response{
			Status: code,
			Msg:    e.GetMsg(code),
		}
	}
	return serializer.BuildListResponse(serializer.BuildOrders(ctx, orderList), uint(total))
}

//func (service *OrderService) Show(ctx context.Context, uId uint, oId string) serializer.Response {
//	orderId, _ := strconv.Atoi(oId)
//	code := e.Success
//	orderDao := dao.NewOrderDao(ctx)
//	order, err := orderDao.GetOrderById(uint(orderId), uId)
//	if err != nil {
//		code = e.Error
//		return serializer.Response{
//			Status: code,
//			Msg:    e.GetMsg(code),
//		}
//	}
//	addressDao := dao.NewAddressDao(ctx)
//	aId := strconv.FormatUint(uint64(service.AddressId), 10)
//	address, err := addressDao.GetAddressByAid(aId)
//	if err != nil {
//		code = e.Error
//		return serializer.Response{
//			Status: code,
//			Msg:    e.GetMsg(code),
//		}
//	}
//
//	productDao := dao.NewProductDao(ctx)
//	product, err := productDao.GetProductById(order.Productid)
//	if err != nil {
//		code = e.Error
//		return serializer.Response{
//			Status: code,
//			Msg:    e.GetMsg(code),
//		}
//	}
//	return serializer.Response{
//		Status: code,
//		Msg:    e.GetMsg(code),
//		Data:   serializer.BuildOrder(order, product, address),
//	}
//}
